package game;

import java.awt.Point;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.LinkedList;

import javax.swing.JButton;
import javax.swing.JFrame;

import utils.JFrameUtil;


/**
 * 贪吃蛇核心代码 2017年7月4日12:00:44
 * 
 * @author XIAOLIANG
 * 
 */
public class SnakeGame {
	// 获得初始化对象
	static SnakeInitData snakeInit = new SnakeInitData();
	// 获得蛇数组
	LinkedList<Point> snake = snakeInit.snake;
	//获得蛇头
	Point snakeHead = snakeInit.snakeHead;

	// 获得刷新显示对象
	static SnakeShowData snakeShowData = new SnakeShowData(snakeInit);

	/*-----------------------------------------------------------------------------------------------------------*/
	/** 5.方向常量 */
	public static final int UP = 1; // up = 上
	public static final int DOWN = -1; // down = 下
	public static final int LEFT = 2; // left = 左
	public static final int RIGHT = -2;// right= 右

	/** 6.当前方向 */
	private static int currentDirection = -2; // 默许向右移动

	public static int getCurrentDirection() {
		return currentDirection;
	}

	/** 游戏结束标记 */
	private static boolean isGameOver = false; // 默认false

	public static boolean isGameOver() {
		return isGameOver;
	}

	/**
	 * 蛇移动的方法
	 * 
	 * @param null
	 */
	public void move() {
		snakeHead = snake.getFirst();

		switch (currentDirection) {
		case UP:
			snake.addFirst(new Point(snakeHead.x, snakeHead.y - 1)); // 向上移动
			break;
		case DOWN:
			snake.addFirst(new Point(snakeHead.x, snakeHead.y + 1)); // 向下移动
			break;
		case LEFT:
			if (snakeHead.x == 1) {
				snake.addFirst(new Point(snakeInit.WIDTH - 2, snakeHead.y)); // 向左移动
																				// 穿墙
			} else {
				snake.addFirst(new Point(snakeHead.x - 1, snakeHead.y)); // 向左移动
			}
			break;
		case RIGHT:
			if (snakeHead.x == snakeInit.WIDTH - 2) {
				snake.addFirst(new Point(1, snakeHead.y)); // 向右移动 穿墙
			} else {
				snake.addFirst(new Point(snakeHead.x + 1, snakeHead.y)); // 向右移动
			}
			break;
		default:
			break;
		}

		// 每走一步判断一下是否吃到食物
		if (eatFood()) {
			// 吃到了食物，生成新的食物
			snakeInit.initFood();
		} else {
			// 没吃到食物，删除蛇尾
			snake.removeLast();
		}

		gameOver(); // 1.要先调用方法，判断游戏是否结束
		refresh(); // 2.然后再刷新地图，否则蛇头在边界时会把地图边界覆盖掉，导致判断失误
		if (isGameOver) {
			System.out.println("》》》》》》》》》》》》游戏结束！《《《《《《《《《《《《《");
			System.exit(0);
		}
	}

	/**
	 * 使用按键的方向替换当前方向
	 * 
	 * @param newDirection
	 */
	public static void changeDirection(int newDirection) {

		// 用当前方向和要移动的方向相加，不等于0，则不是逆行
		if ((currentDirection + newDirection) != 0) {

			currentDirection = newDirection;
		}
	}

	/**
	 * 吃食物
	 */
	public boolean eatFood() {
		Point snakeHead = snake.getFirst();

		// 蛇头坐标等于食物坐标，吃到了食物
		if (snakeHead.equals(snakeInit.food)) {
			return true;
		}
		return false;
	}

	/**
	 * 刷新 地图、食物、蛇的状态
	 */
	public void refresh() {
		snakeInit.initMap(); // 先要初始化地图，清除掉上一步蛇走过的痕迹，否则蛇会在没有吃食物的情况下越走越长
		snakeShowData.showFood(); // 刷新食物
		snakeShowData.showSnake(); // 刷新蛇
		snakeShowData.showMap(); // 刷新地图
	}

	/**
	 * 结束游戏，
	 * 
	 * @param null
	 */
	public void gameOver() {

		Point snakeHead = snake.getFirst();

		// 撞墙
		if (snakeInit.map[snakeHead.y][snakeHead.x] == '*') {
			isGameOver = true;
		}

		// 撞到自己身体
		for (int i = 1; i < snake.size(); i++) {
			Point body = snake.get(i);
			if (snakeHead.equals(body)) {
				isGameOver = true;
			}
		}
	}

	/*-----------------------------------------------------------------------------------------------------------*/

	public static void main(String[] args) throws Exception {
		
		SnakeGame snakeGame = new SnakeGame();

		System.out.println(snakeInit.snake);

		// 地图，食物，蛇的初始化和显示
		snakeInit.initMap();
		snakeInit.initFood();
		snakeInit.initSnake();
		snakeShowData.showSnake();
		snakeShowData.showFood();
		snakeShowData.showMap();

		// 绘制开始游戏按键
		JFrame jFrame = new JFrame("贪吃蛇");
		JButton button = new JButton("开始游戏");
		jFrame.add(button);
		JFrameUtil.initWindow(jFrame, 100, 100);

		/** -----------------------监听按键事件-------------------------- */
		button.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				int code = e.getKeyCode();

				switch (code) {
				case KeyEvent.VK_UP: // 上
					changeDirection(UP);
					break;
				case KeyEvent.VK_DOWN: // 下
					changeDirection(DOWN);
					break;
				case KeyEvent.VK_LEFT: // 左
					changeDirection(LEFT);
					break;
				case KeyEvent.VK_RIGHT: // 右
					changeDirection(RIGHT);
					break;
				default:
					break;
				}
				// snakeGame.move();
			}
		});

		// 循环执行游戏，让蛇从游戏开始就走动
		while (true) {
			Thread.sleep(200); // 延时300ms
			snakeGame.move();
		}
	}

}
